home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / windows4 / pcproj.zip / GANTTWIN.CLS < prev    next >
Text File  |  1990-01-15  |  7KB  |  246 lines

  1. /* Maintain a Gantt chart in a Window. The GanttWindow is
  2.    responsible for drawing the project.
  3.  
  4.    GanttWindow descends from the Window class and inherits all
  5.    of its methods and instance variables.
  6. */!!
  7.  
  8. inherit(Window, #GanttWindow, #(project     /* the project */
  9. activities  /* in the project */
  10. barWidth    /* width of a unit */
  11. barHeight   /* based on scrnsize */
  12. activHeight /* bar + dead space */), 2, nil)!!
  13.  
  14. now(GanttWindowClass)!!
  15.  
  16. /* Return the name of this class's MS-Windows window class
  17.   either for registration or new window creation. */
  18. Def wndClass(self)
  19. { ^"GanttWindow"  }!!
  20.  
  21. /* Create a new window class Struct.
  22.    Change the cursor to a cross.  */
  23. Def newWClass(self, lpCl, lpIcon | wc)
  24. { wc := newWClass(self:WindowClass, lpCl, lpIcon);
  25.   putWord(wc, Call LoadCursor(0, IDC_CROSS), 14);
  26.   ^wc;
  27. } !!
  28.  
  29. now(GanttWindow)!!
  30.  
  31. /* See if the user has double clicked on a bar.
  32.    If so, bring up a dialog for editing. */
  33. Def  WM_LBUTTONDBLCLK(self, wP, lP | idx)
  34. {
  35.   idx:= (y(asPoint(lP)) - barHeight) / activHeight;
  36.   if idx <= size(activities) - 1 
  37.     if editInfo(activities[idx]) == IDOK
  38.       dirty(self);
  39.     endif;
  40.   else
  41.     beep();
  42.   endif;
  43. }!!
  44.  
  45. /* For a Task, draw a critical bar.  Make sure we don't draw
  46.    draw over the titles if the node hasn't been hooked up yet.
  47.    Uses early binding, direct Windows calls for speed. */
  48. Def  drawTask(self, aNode, x, y, hDC | startX, hBrush)
  49. {
  50.    startX := max(GW_STARTX, x - asInt(getTime(aNode)*barWidth));
  51.    
  52.    hBrush := Call CreateSolidBrush(CritColor);
  53.    Call SelectObject(hDC, hBrush);   
  54.    Call FillRect(hDC, rect(startX:Int, y, x, y+barHeight), hBrush);
  55.    Call Rectangle(hDC, startX, y, x, y+barHeight);
  56.    Call DeleteObject(Call SelectObject(hDC, hBrush));
  57. }!!
  58.  
  59. /* Create the window using a regular window style. */
  60. Def  create(self, par, wName, rect, style)
  61.   ^create(self:Window, par, wName, rect, 
  62.      WS_POPUPWIND);
  63. }!!
  64.  
  65. /* If we close, be sure to tell the parent. 
  66.    For testing a standalone Gantt chart delete this method. */
  67. Def  close(self)
  68. {
  69.   close(self:Window);
  70.   closeGantt(parent);  /* assumes parent is a ProjWindow */
  71. }!!
  72.  
  73. /* Make sure the parent window knows that the project
  74.    has changed. */
  75. Def  dirty(self)
  76. {
  77.   invalidate(self);
  78.   invalidate(parent);
  79. }!!
  80.  
  81. /* Set up a dummy project, menus and the method table. */
  82. Def  init(self)
  83. {  
  84.   setProject(self, new(Project));
  85.   recalc(project);  
  86.   setMenus(self);
  87.   setResolution(self);
  88. }!!
  89.  
  90. /* Set the resolution for the size of bars, spacing etc.
  91.    For CGA, bars should be smaller. */
  92. Def  setResolution(self | hDC, ts)
  93. {
  94.   hDC := getContext(self);
  95.   ts := textSize(self, hDC);
  96.   releaseContext(self, hDC);
  97.   barHeight := y(ts);
  98.   activHeight := asInt(1.25 * y(ts));
  99. }!!
  100.  
  101. /* Handle menu commands. */
  102. Def  command(self, wp, lp)
  103. {
  104.   select
  105.     case wp == PW_HELP
  106.       help(self);
  107.     endCase
  108.     case wp == PW_VIEW_GANTT  /* open or close, same key */
  109.       close(self);
  110.     endCase
  111.     case wp == PW_FILE_PRINT_GRAPH
  112.       printWindow(self, 1);
  113.     endCase
  114.     case wp == PW_CLIP
  115.       clipWindow(self, 1);
  116.     endCase
  117.   endSelect;
  118. }!!
  119.  
  120. /* Load menu resources. */
  121. Def  setMenus(self)
  122. {
  123.   loadMenu(self, "GWMenus");
  124.   setMenu(self, hMenu);
  125. }
  126. !!
  127.  
  128. /* Display help information from resource file. */
  129. Def  help(self | dlg)
  130. {
  131.   dlg := new(Dialog);
  132.   checkRunModal(dlg, GW_HELP_BOX, self);
  133. }!!
  134.  
  135. /* Draw a Milestone diamond in the window. */
  136. Def  drawMilestone(self, aNode, x, y, hDC)
  137. {
  138.     Call SelectObject(hDC, stock(WHITE_BRUSH));
  139.     draw(new(WinPolygon,
  140.       tuple(
  141.         point(x, y),                 /* top */
  142.         point(x - GW_DMWIDTH, 
  143.               y + barHeight/2),      /* left */
  144.         point(x, y + barHeight),     /* bottom */
  145.         point(x + GW_DMWIDTH,
  146.               y + barHeight/2)       /* right */
  147.       )), hDC);
  148. }!!
  149.  
  150. /* Draw a slack bar in the window. 
  151.    Uses direct Windows call for speed. */
  152. Def  drawSlackBar(self, aNode, x, y, hDC | hBrush)
  153. {
  154.    Call FillRect(hDC, rect(x:Int, y, 
  155.                 x + asInt(getSlack(aNode)*barWidth),
  156.                 y + barHeight), stock(GRAY_BRUSH)
  157.            );
  158. }!!
  159.  
  160. /* Draw text info in the window. */
  161. Def  drawTextInfo(self, aNode, x, y, hDC | str)
  162. {
  163.       if critical(aNode)
  164.         Call SetTextColor(hDC, CritColor);
  165.         str := "*" + getName(aNode);
  166.       else
  167.         Call SetTextColor(hDC, SlackColor);
  168.         str := " " + getName(aNode);
  169.       endif;
  170.       Call TextOut(hDC, x, y, str, size(str));  
  171. }!!
  172.  
  173. /* Set the bar width so that the chart fits in the window. 
  174.    Adjust in case it's very large or very small. */
  175. Def  setBarWidth(self, time)
  176. {
  177.   barWidth := asInt((right(clientRect(self)) - GW_STARTX) / 
  178.                 (time + 1));
  179.   barWidth := min(75, max(2, barWidth));
  180. }!!
  181.  
  182. /* Set the project. */
  183. Def  setProject(self, aProject)
  184. {
  185.   project := aProject;
  186.   recalc(project);
  187. }!!
  188.  
  189. /* Draw the axis for the window. 
  190.    Uses direct Windows calls for speed. */
  191. Def  drawAxis(self, hDC | endX, endY, str)
  192. {
  193.     endX := GW_STARTX + barWidth * 
  194.                (max(2,asInt(getTime(project)+getSlack(project)))) ;  
  195.     endY := activHeight * (size(nodes(project))+1); 
  196.        
  197.     /* draw a rectangle for x and y axis */ 
  198.     
  199.     Call Rectangle(hDC, GW_STARTX, GW_STARTY, endX, endY+1);
  200.         
  201.     /* draw notches on the x axis */    
  202.     do(overBy(GW_STARTX, endX, barWidth),
  203.       {using(i) 
  204.         Call MoveTo(hDC, i, GW_STARTY);           /* top */
  205.         Call LineTo(hDC, i, GW_STARTY + GW_NOTCH);
  206.         Call MoveTo(hDC, i,endY);                 /* bot */
  207.         Call LineTo(hDC, i, endY - GW_NOTCH);
  208.     });
  209.     str := asString(getEarlyStart(project));    
  210.     Call TextOut(hDC, GW_STARTX, endY + 10, str, size(str));  
  211. }!!
  212.  
  213. /* Respond to MS-Windows messages to paint the window. 
  214.    Show the project as a Gantt chart. 
  215.    Draw the axis, then for each node draw the graphics. */
  216. Def  paint(self, hDC | y, t)
  217. {
  218.   setBarWidth(self, asInt(getTime(project)+getSlack(project)));
  219.   activities := sortedActivities(project);
  220.   
  221.   drawAxis(self, hDC);
  222.   y := barHeight;         /* starting positions for bars */
  223.   
  224.   do(activities,
  225.     {using(aNode) 
  226.    
  227.      drawTextInfo(self, aNode, 10, y, hDC);
  228.      
  229.       /* make a temp to avoid calculating starting position */
  230.       t := max(GW_STARTX, GW_STARTX + barWidth *
  231.             asInt(getEarlyStart(aNode)-getEarlyStart(project)+getTime(aNode)));
  232.       
  233.       /* draw a slack bar if necessary. */  
  234.       if getSlack(aNode) > 0  
  235.         drawSlackBar(self, aNode, t, y, hDC)
  236.       endif;
  237.  
  238.       draw(aNode, self, t, y, hDC);  /* node knows how */
  239.  
  240.       y := y + activHeight;     /* move down for next bar */
  241.   });
  242. }!!
  243.  
  244.  
  245.